/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ig.da.insert;

import ig.da.abs.AbsDA;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.NamingException;

/**
 *
 * @author jsanchez
 */
public class Plano extends AbsDA {

    public Plano() throws NamingException, SQLException, ClassNotFoundException {
        super();
    }

    @Override
    public void procesar() throws Exception {
        this.getStatementDelete().execute("TRUNCATE TABLE " + getTabla());
        Integer n = 3;
        Statement[] insert = new Statement[n];
        Plano.InserTable[] inserTables = new Plano.InserTable[n];

        /**
         * Creacion de Statemet para Insercion
         */
        this.getPreparedStatementInsert();
        for (int i = 0; i < insert.length; i++) {
            insert[i] = this.getStatementInsert();
//            for (int j = 1; j <= this.getNumCols(); j++) {
//                insert[i].setNull(j, java.sql.Types.CHAR);
//            }
        }
        /**
         * Inicializacion de los Hilos de trabajo y ejecucion
         */
        for (int i = 0; i < inserTables.length; i++) {
            inserTables[i] = new InserTable(insert[i], "Thread->" + i);
            ((InserTable) inserTables[i]).start();
        }

        int lineas = 0;
        System.out.println("Procesando Plano");
        while (this.readLine() != null) {//lee cada una de las lineas del plano
            PilaLienas.push(this.getToken());//adiciona un vector de campos al final de la pila
            lineas++;
            if (PilaLienas.size() >= 90000) {
                try {
                    //System.out.println("PilaLienas.size:" + PilaLienas.size());
                    while (PilaLienas.size() > 15000) {
                        Thread.sleep(200);
                    }
                } catch (Exception exception) {
                    System.out.println("Out-sleep-err sleep->500");
                }
            }
        }
        System.out.println("Total linea:" + lineas);
        while (PilaLienas.size() > 0) {
            try {
                Thread.sleep(3000);
                System.out.println("OK-PilaLienas.size:" + PilaLienas.size());
            } catch (Exception exception) {
                System.out.println("Out-sleep-err sleep->3000");
            }
        }
        Integer totalsumathread = 0;
        for (int i = 0; i < inserTables.length; i++) {
            totalsumathread += ((InserTable) inserTables[i]).getInsertados();
            ((InserTable) inserTables[i]).setFinalizar(true);
        }
        
        boolean ok = true;
        while (ok) {
            ok = false;
            for (int i = 0; i < inserTables.length; i++) {
                boolean listo=((InserTable) inserTables[i]).isOk();                
                if(!listo){
                    ok = true;
                }                
            }
        }
        
        //getMetricada().close();
        System.out.println("totalsumathread:" + totalsumathread);
    }
    private java.util.Stack PilaLienas = new java.util.Stack();

    /***
     * Clase que implementa la insercion de cada una de las lineas en la tabla seleccionada
     */
    class InserTable extends Thread {

        private Statement insert = null;
        private boolean finalizar = false;
        private String nombre;
        private boolean ok = false;

        public InserTable(Statement insert, String nombre) {
            this.insert = insert;
            this.nombre = nombre;
        }

        public void setFinalizar(boolean finalizar) {
            this.finalizar = finalizar;
        }

        public boolean isFinalizar() {
            return finalizar;
        }
        Integer insertados = 0;

        public Integer getInsertados() {
            return insertados;
        }

        @Override
        public void run() {
            super.run();
            String QUERY = getQueryNull();
            String[] myToken = null;
            try {
                String[] QTemp = QUERY.split("NULL");
                while (!finalizar) {
                    try {
                        myToken = (String[]) PilaLienas.pop();
                    } catch (Exception exception) {
                        myToken = null;
                    }
                    if (myToken != null) {
                        String QEjecutar = QTemp[0];
                        for (int i = 0; i < QTemp.length - 1; i++) {
                            try {
                                QEjecutar += "'" + myToken[i] + "'" + QTemp[i + 1];
                            } catch (Exception exception) {
                                QEjecutar += "NULL" + QTemp[i + 1];
                            }
                        }
                        insert.addBatch(QEjecutar);
                        insertados++;
                        if (insertados % 15000 == 0) {
                            System.out.println(nombre + ": insertando ");
                            insert.executeBatch();
                            insert.clearBatch();
                        }
                    } else {
                        sleep(500);
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                try {
                    insert.executeBatch();
                    insert.clearBatch();
                } catch (Exception exception) {
                    System.out.println(nombre + ": Not Batch ..");
                }
                try {
                    insert.close();
                } catch (Exception ex) {
                    System.out.println(nombre + ": Not Closing Statement ..");
                }
            }
            try {
                this.finalize();
            } catch (Throwable ex) {
                System.out.println(nombre + ": Not finalize ..");
            }
            System.out.println(nombre + ": Insertados :" + insertados);
            this.ok = true;
        }

        public boolean isOk() {
            return ok;
        }
        
    }
}
